CMP_SOURCES = {
    luasnip = { name = "luasnip", menu = "[Snip]" },
    nvim_lsp = {
        name = "nvim_lsp",
        menu = "[LSP]",
        entry_filter = function(entry)
            return require("cmp").lsp.CompletionItemKind.Snippet ~= entry:get_kind()
        end,
    },
    path = { name = "path", menu = "[Path]" },
    buffer = { name = "buffer", menu = "[Buf]" },
    cmdline = { name = "cmdline", menu = "[Cmd]" },
    -- vsnip = {name = "vsnip", menu = "[VSnip]"},
    sign = { name = 'nvim_cmp_sign' , menu = "[SIGN]"}, -- 新增：签名（参数）补全
}


return {
    "hrsh7th/nvim-cmp",
    dependencies = {
        -- cmp-nvim-lsp in lsp/init.lua
        "hrsh7th/cmp-nvim-lsp",
        "hrsh7th/cmp-cmdline",
        "hrsh7th/cmp-buffer",
        "hrsh7th/cmp-path",
        "onsails/lspkind-nvim",
        -- "hrsh7th/cmp-vsnip",
        "crazyhulk/cmp-sign", -- 函数签名
    },
    event = { "InsertEnter", "CmdlineEnter" },
    config = function()
        local cmp = require("cmp");
        local compare = require("cmp.config.compare");
        local lspkind = require("lspkind");

        cmp.setup({
            -- 补全窗口样式
            window = {
                completion = cmp.config.window.bordered({  -- 补全菜单窗口
                    border = "none",  -- 无边框
                    -- 窗口高亮组：普通文本、边框、选中项分别使用的颜色
                    winhighlight = "Normal:Normal,FloatBorder:Normal,CursorLine:MyCmpSel",
                }),
                documentation = cmp.config.window.bordered({  -- 补全文档窗口（显示详情）
                    border = "none",  -- 无边框
                }),
            },

            -- 补全项显示格式
            -- formatting = {
            --     fields = {
            --         "abbr",
            --         "kind",
            --         "menu"
            --     },  -- 显示内容：缩写、类型、来源
            --     expandable_indicator = false,  -- 不显示展开指示器（省略号）
            --     format = function(entry, vim_item)
            --         -- 为补全项添加来源标识（如 [LSP] [Snip]）
            --         vim_item.menu = CMP_SOURCES[entry.source.name].menu
            --         return vim_item
            --     end,
            -- },
            formatting = {
                expandable_indicator = false,
                format = lspkind.cmp_format({
                    with_text = true,
                    maxwidth = 50,
                    before = function (entry, vim_item)
                        -- vim_item.menu = "["..string.upper(entry.source.name).."]"
                        -- vim_item.menu = CMP_SOURCES[entry.source.name].menu
                        vim_item.menu = ({ nvim_lsp = "" })["clangd"]
                        return vim_item
                    end,
                })
            },

            -- 实验性功能：关闭幽灵文本（输入时自动提示的灰色补全预览）
            experimental = { ghost_text = false },

            -- 启用的补全来源（按优先级排序，靠前的优先显示）
            sources = cmp.config.sources({
                CMP_SOURCES.nvim_lsp,  -- LSP 补全（优先级最高）
                CMP_SOURCES.sign,
                -- { name = 'nvim_cmp_sign' },
                CMP_SOURCES.vsnip,   -- 代码片段补全
                CMP_SOURCES.buffer,    -- 缓冲区内容补全
                CMP_SOURCES.path,      -- 文件路径补全
            }),

            -- 补全项排序规则（权重从高到低）
            sorting = {
                comparators = {
                    compare.score,     -- 按匹配分数排序（分数高的优先）
                    compare.kind,      -- 按补全类型排序（如函数 > 变量）
                    compare.exact,     -- 精确匹配优先
                    compare.length,    -- 短内容优先
                    compare.offset,    -- 按在代码中的位置排序
                    compare.sort_text, -- 按预定义的排序文本排序
                },
            },

            mapping = {
                ["<Tab>"] = cmp.mapping(function(fallback)
                    -- This little snippet will confirm with tab, and if no entry is selected, will confirm the first item
                    if cmp.visible() then
                        local entry = cmp.get_selected_entry()
                        if not entry then
                            cmp.select_next_item({ behavior = cmp.SelectBehavior.Select })
                        end
                        cmp.confirm()
                    else
                        fallback()
                    end
                end, {"i","s","c",}),

                -- Ctrl+空格：切换补全菜单（显示/隐藏）
                ["<C-Space>"] = cmp.mapping(function(fallback)
                    if cmp.visible() then
                        cmp.abort()  -- 已显示则关闭
                    else
                        cmp.complete()  -- 未显示则打开
                    end
                end),

                ["<C-n>"] = cmp.mapping.select_next_item(),
                ["<C-p>"] = cmp.mapping.select_prev_item(),

                
            },
        });
        -- 为搜索模式（/ 和 ?）配置补全
        for _, cmd_type in ipairs({ "/", "?" }) do
            cmp.setup.cmdline(cmd_type, {
                mapping = cmp.mapping.preset.cmdline(),  -- 使用命令行模式默认快捷键
                sources = {
                    CMP_SOURCES.buffer,  -- 仅启用缓冲区内容补全（搜索当前文件中的内容）
                },
            })
        end

        -- 为命令行（: 开头的命令）配置补全
        cmp.setup.cmdline(":", {
            mapping = cmp.mapping.preset.cmdline(),  -- 使用命令行模式默认快捷键
            sources = {
                -- 优先显示路径补全（group_index=1），其次显示命令补全（group_index=2）
                vim.tbl_extend("force", CMP_SOURCES.path, { group_index = 1 }),
                vim.tbl_extend("force", CMP_SOURCES.cmdline, { group_index = 2 }),
            },
        });

        local capabilities = require('cmp_nvim_lsp').default_capabilities();

        -- vim.lsp.config["clangd"].setup({
        --     capabilities = capabilities,
        -- });



    end,
}
